package gui;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

import logic.ChessGame;
import logic.IPlayerHandler;
import logic.Move;
import logic.Piece;

public class ConsoleGUI implements IPlayerHandler {

	private ChessGame chessGame;

	public ConsoleGUI(ChessGame chessGame) {
		this.chessGame = chessGame;
	}

	public void run() {

		String input = "";
		BufferedReader inputReader = new BufferedReader(new InputStreamReader(
				System.in));
		while (true) {
			// print game state and ask for user input
			// printCurrentGameState();
			System.out.println("Your move (example: e 3 e 4)");
			try {
				// read user input
				input = inputReader.readLine();

				// exit, if user types 'exit'
				if (input.equalsIgnoreCase("exit")) {
					return;
				} else {
					this.handleMove(input);
					this.chessGame.changeGameState();
				}
			} catch (Exception e) {
				System.out.println(e.getClass() + ": " + e.getMessage());
			}

		}
	}

	private void handleMove(String input) {
		StringTokenizer st = new StringTokenizer(input, " ");
		String strSourceColumn = st.nextToken();
		String strSourceRow = st.nextToken();
		String strTargetColumn = st.nextToken();
		String strTargetRow = st.nextToken();

		int sourceColumn = 0;
		int sourceRow = 0;
		int targetColumn = 0;
		int targetRow = 0;

		sourceColumn = convertColumnStrToColumnInt(strSourceColumn);
		sourceRow = convertRowStrToRowInt(strSourceRow);
		targetColumn = convertColumnStrToColumnInt(strTargetColumn);
		targetRow = convertRowStrToRowInt(strTargetRow);
		Move move = new Move(sourceRow, sourceColumn, targetRow, targetColumn);
		chessGame.movePiece(move);
	}

	private int convertRowStrToRowInt(String strRow) {
		if (strRow.equalsIgnoreCase("1")) {
			return Piece.ROW_1;
		} else if (strRow.equalsIgnoreCase("2")) {
			return Piece.ROW_2;
		} else if (strRow.equalsIgnoreCase("3")) {
			return Piece.ROW_3;
		} else if (strRow.equalsIgnoreCase("4")) {
			return Piece.ROW_4;
		} else if (strRow.equalsIgnoreCase("5")) {
			return Piece.ROW_5;
		} else if (strRow.equalsIgnoreCase("6")) {
			return Piece.ROW_6;
		} else if (strRow.equalsIgnoreCase("7")) {
			return Piece.ROW_7;
		} else if (strRow.equalsIgnoreCase("8")) {
			return Piece.ROW_8;
		} else if (strRow.equalsIgnoreCase("9")) {
			return Piece.ROW_9;
		} else if (strRow.equalsIgnoreCase("10")) {
			return Piece.ROW_10;
		} else {
			throw new IllegalArgumentException("invalid row: " + strRow);
		}
	}

	private int convertColumnStrToColumnInt(String strColumn) {
		if (strColumn.equalsIgnoreCase("a")) {
			return Piece.COLUMN_A;
		} else if (strColumn.equalsIgnoreCase("b")) {
			return Piece.COLUMN_B;
		} else if (strColumn.equalsIgnoreCase("c")) {
			return Piece.COLUMN_C;
		} else if (strColumn.equalsIgnoreCase("d")) {
			return Piece.COLUMN_D;
		} else if (strColumn.equalsIgnoreCase("e")) {
			return Piece.COLUMN_E;
		} else if (strColumn.equalsIgnoreCase("f")) {
			return Piece.COLUMN_F;
		} else if (strColumn.equalsIgnoreCase("g")) {
			return Piece.COLUMN_G;
		} else if (strColumn.equalsIgnoreCase("h")) {
			return Piece.COLUMN_H;
		} else if (strColumn.equalsIgnoreCase("i")) {
			return Piece.COLUMN_I;
		} else {
			throw new IllegalArgumentException("invalid column: " + strColumn);
		}
	}

	public static void printCurrentGameState(ChessGame chessGame) {
		// TODO Auto-generated method stub
		for (int row = Piece.ROW_1; row <= Piece.ROW_10; row++) {
			String rowStr = "";
			for (int column = Piece.COLUMN_A; column <= Piece.COLUMN_I; column++) {
				Piece piece = chessGame.getNonCapturedPieceAtLocation(row,
						column);
				String pieceStr = getNameOfPiece(piece) == "  " ? " +"
						: getNameOfPiece(piece);
				rowStr += pieceStr;
				if (column < Piece.COLUMN_I)
					rowStr += "--";
			}
			System.out.println(rowStr);
			if (row < Piece.ROW_10)
				System.out.println(" |   |   |   |   |   |   |   |   |");
		}

		String turnColor = (chessGame.getGameState() == ChessGame.GAME_STATE_GREEN) ? "green"
				: "red";
		System.out.println("turn: " + turnColor);
	}

	private static String getNameOfPiece(Piece piece) {
		if (piece == null) {
			return "  ";
		}

		String strColor = "";
		switch (piece.getColor()) {
		case Piece.COLOR_GREEN:
			strColor = "G";
			break;
		case Piece.COLOR_RED:
			strColor = "R";
			break;
		default:
			strColor = "?";
			break;
		}

		String strType = "";
		switch (piece.getType()) {
		case Piece.TYPE_CANNON:
			strType = "C";
			break;
		case Piece.TYPE_ELEPHANT:
			strType = "E";
			break;
		case Piece.TYPE_GUARD:
			strType = "G";
			break;
		case Piece.TYPE_KING:
			strType = "K";
			break;
		case Piece.TYPE_HOURSE:
			strType = "H";
			break;
		case Piece.TYPE_PAWN:
			strType = "P";
			break;
		case Piece.TYPE_ROOK:
			strType = "R";
			break;
		default:
			strType = "?";
			break;
		}
		return strColor + strType;
	}

	public static void main(String[] args) {

		ChessGame chessGame = new ChessGame();
		ConsoleGUI console = new ConsoleGUI(chessGame);
		chessGame.setPlayer(Piece.COLOR_GREEN, console);
		chessGame.setPlayer(Piece.COLOR_RED, console);
		chessGame.startGame();
	}

	@Override
	public Move getMove() {
		System.out.println("your move (format: e3-e4): ");
		Move move = null;
		while (move == null) {
			// read user input
			BufferedReader inputReader = new BufferedReader(
					new InputStreamReader(System.in));
			String input = "";
			try {
				input = inputReader.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}

			// exit, if user types 'exit'
			if (input.equalsIgnoreCase("exit"))
				System.exit(0);
			else
				move = this.convertStringToMove(input);
		}

		return move;
	}

	private Move convertStringToMove(String input) {
		StringTokenizer st = new StringTokenizer(input);
		String strSourceColumn = st.nextToken();
		String strSourceRow = st.nextToken();
		String strTargetColumn = st.nextToken();
		String strTargetRow = st.nextToken();

		int sourceColumn = 0;
		int sourceRow = 0;
		int targetColumn = 0;
		int targetRow = 0;

		sourceColumn = convertColumnStrToColumnInt(strSourceColumn);
		sourceRow = convertRowStrToRowInt(strSourceRow);
		targetColumn = convertColumnStrToColumnInt(strTargetColumn);
		targetRow = convertRowStrToRowInt(strTargetRow);
		Move move = new Move(sourceRow, sourceColumn, targetRow, targetColumn);
		return move;
	}

	@Override
	public void moveSuccessfullyExecuted(Move move) {
		// printCurrentGameState();
		if (this.chessGame.getGameState() == ChessGame.GAME_STATE_GREEN)
			System.out.println("green turn");
		else if (this.chessGame.getGameState() == ChessGame.GAME_STATE_RED)
			System.out.println("red turn");
	}
}
